<template>
  <div class="chat-container">
    <h2>Chat Room: {{ roomId }}</h2>
    <button @click="switchRoom">Switch Room</button>
    <button @click="reconnectWithToken">Reconnect with Token</button>
    <div>
      <label for="token-input">Token:</label>
      <input id="token-input" v-model="newToken" type="text" placeholder="Enter new token" />
    </div>
    <div>
      <label for="sessionId-input">SessionId:</label>
      <input id="sessionId-input" v-model="sessionId" type="text" placeholder="Enter Session ID" />
    </div>
    <div class="messages" ref="messageContainer">
      <ul>
        <li v-for="(msg, index) in messages" :key="index" class="message-item">
          <img v-if="msg.headimg" :src="msg.headimg" alt="User Avatar" class="avatar" />
          <div class="message-content">
            <strong>{{ msg.nickname || msg.username }}</strong>: {{ msg.content }}
          </div>
        </li>
      </ul>
    </div>
    <div class="message-input">
      <input v-model="message" placeholder="Type a message" @keydown.enter="handleSendMessage" />
      <button @click="handleSendMessage">Send</button>
    </div>
  </div>
</template>

<script>
import { createWebSocket, keepAlive } from "../services/websocket";

export default {
  props: ["token", "serverUrl"],
  data() {
    return {
      message: "",
      messages: [],
      roomId: "room1",
      ws: null,
      heartbeat: null,
      reconnectInterval: 5000,
      reconnecting: false,
      newToken: this.token,
      sessionId: "",
    };
  },
  mounted() {
    this.sessionId = new Date().getTime();
    this.connectWebSocket();
  },
  beforeDestroy() {
    this.cleanupWebSocket();
  },
  methods: {
    connectWebSocket() {
      if (this.reconnecting) return;
      this.reconnecting = true;

      this.ws = createWebSocket(
          this.serverUrl,
          this.newToken,
          this.roomId,
          this.sessionId,
          this.handleIncomingMessage
      );
      this.ws.onopen  = () => {
        console.info("WebSocket opened.");
        this.reconnectInterval = 5000;
      };

      this.ws.onclose = () => {
        console.warn("WebSocket closed. Attempting to reconnect...");
        this.cleanupWebSocket();
        if (this.reconnectInterval > 0){
          setTimeout(() => {
            this.reconnecting = false;
            if (this.reconnectInterval > 0) {
              this.connectWebSocket();
            }
          }, this.reconnectInterval);
        }
      };

      this.heartbeat = keepAlive(this.ws);
    },

    cleanupWebSocket() {
      if (this.ws) {
        this.ws.close();
        this.ws = null;
      }
      if (this.heartbeat) {
        this.heartbeat();
        this.heartbeat = null;
      }
    },

    handleIncomingMessage(message) {
      if (!message || !message.type) return;
      switch (message.type) {
        case "kick":
          console.error("Received kick message");
          this.cleanupWebSocket();
          this.reconnectInterval = -1;
          break;
        case "error":
          console.error("Received error message:", message.content);
          break;
        case "pong":
          console.log("Received pong message");
          return;
        case "chat":
          message.nickname = message.nickname || message.username;
          break;
        case "system":
          // Handle system messages if needed
          break;
        default:
          return;
      }

      this.messages.push(message);
      this.scrollToBottom();
    },

    switchRoom() {
      const newRoomId = prompt("Enter new room ID:", "");
      if (newRoomId) {
        this.roomId = newRoomId;
        this.cleanupWebSocket();
        this.connectWebSocket();
      }
    },

    reconnectWithToken() {
      if (this.newToken) {
        this.cleanupWebSocket();
        this.connectWebSocket();
      } else {
        alert("Please enter a valid token.");
      }
    },

    handleSendMessage() {
      if (this.ws && this.ws.readyState === WebSocket.OPEN && this.message.trim()) {
        this.ws.send(
            JSON.stringify({
              type: "chat",
              content: this.message.trim(),
            })
        );
        this.message = "";
      }
    },

    scrollToBottom() {
      this.$nextTick(() => {
        const container = this.$refs.messageContainer;
        if (container) {
          container.scrollTop = container.scrollHeight;
        }
      });
    },
  },
};
</script>

<style scoped>
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  max-width: 600px;
  margin: auto;
}

.messages {
  flex: 1;
  overflow-y: auto;
  margin: 10px 0;
  border: 1px solid #ccc;
  padding: 10px;
}

.message-item {
  display: flex;
  margin-bottom: 10px;
}

.avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  margin-right: 10px;
}

.message-content {
  flex: 1;
}

.message-input {
  display: flex;
  gap: 10px;
}
</style>
